

<template>


  <el-card shadow="hover">
    <div class="bar_btn_div">
      <div class="title_div">
        <div>筛选</div>
      </div>
      <div>
        <el-button-group class="btn-add">
          <el-button style="float:right" type="primary" @click="query()" size="small">查询搜索</el-button>
          <el-button style="float:right;margin-right: 15px" @click="handleResetSearch()" size="small">重置</el-button>
        </el-button-group>
      </div>
    </div>
    <div class="search_div">
      <el-form :model="state.listQuery.params" size="small" label-width="140px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="ObjectId">
              <el-input v-model="state.listQuery.params._id" class="input-width" placeholder="请输入ObjectId"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="文件名称">
              <el-input v-model="state.listQuery.params.filename" class="input-width" placeholder="请输入文件名称，支持正则表达式查询"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="6">
            <el-form-item label="文件大小范围">
              <el-input v-model.number="state.listQuery.params.minSize" class="input-width" placeholder="文件大小最小值"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="至">
              <el-input v-model.number="state.listQuery.params.maxSize" class="input-width" placeholder="文件大小最大值"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="所属用户">
              <el-input v-model.number="state.listQuery.params.metadata.ownerName" class="input-width" placeholder="所属用户,支持正则表达式"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="7">
            <el-form-item label="上传时间">
              <div class="block">
                <el-date-picker v-model="state.listQuery.params.uploadDate" type="datetimerange" range-separator="至" start-placeholder="开始日期"
                  end-placeholder="结束日期" align="right"></el-date-picker>
              </div>
            </el-form-item>
          </el-col>
          <el-col :span="5">
            <el-form-item label="文件标签(tag)">
              <el-input v-model.number="state.listQuery.params.metadata.tag" class="input-width" placeholder="文件标签(tag),支持正则表达式"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="5">
            <el-form-item label="文件类型">
              <div class="block">
                <el-select clearable v-model="state.listQuery.params.metadata.suffix" width="120">
                  <el-option v-for="item in state.fileType" :key="item.value" :label="item.name" :value="item.value" autocomplete="on" />
                </el-select>
              </div>
            </el-form-item>
          </el-col>
          <el-col :span="7" :hidden="state.pageType == 'public'">
            <el-form-item label="文件权限">
              <div class="block">
                <el-radio-group v-model="state.listQuery.params.metadata.fileAuthRange">
                  <el-radio>全部</el-radio>
                  <el-radio label="personal">个人</el-radio>
                  <el-radio label="resource" v-if="state.pageType == 'admin'">资源文件</el-radio>
                  <el-radio label="public">公共</el-radio>
                </el-radio-group>
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>

    <div class="bar_btn_div" style="padding:10px;padding-left:20px;padding-right:20px">
      <div class="title_div">
        <div>操作</div>
      </div>
      <el-button-group class="btn-add">
        <el-button @click="handleDelete()" v-if="pageType != 'public'">删除</el-button>
        <el-button type="primary" @click="openUploadDialog()" v-if="pageType != 'public'">文件上传</el-button>
      </el-button-group>
    </div>
    <el-card style="margin-top: 20px;" shadow="hover" class="layout-padding-auto">
      <el-table size="default" :data="state.gridFsFileList.list" style="width: 100%" ref="dataListTable" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="50"></el-table-column>
        <el-table-column label="ObjectId" prop="_id" width="210"></el-table-column>
        <el-table-column label="文件名" prop="filename" width="150"></el-table-column>
        <el-table-column label="文件大小" prop="length" width="120"></el-table-column>
        <el-table-column label="上传时间" prop="uploadDate" width="140"></el-table-column>
        <el-table-column label="chunkSize" prop="chunkSize" width="120"></el-table-column>
        <el-table-column label="Metadata" prop="metadata">
          <template #default="scope">{{ JSON.stringify(scope.row.metadata) }}</template>
        </el-table-column>
        <el-table-column label="操作" width="140">
          <template #default="scope">
            <el-button-group size="mini">
              <el-button type="primary" size="mini" v-if="pageType != 'public'" @click="handleDeleteOne(scope.row._id)">删除</el-button>
              <el-button size="mini" v-if="scope.row.metadata.contentType.startsWith('image')" type="primary"
                @click="handleShowImage(scope.row._id, scope.row.filename, scope.row.metadata.contentType)">查看</el-button>
              <el-button v-else type="primary" size="mini"
                @click="handleDownload(scope.row._id, scope.row.filename, scope.row.metadata.contentType)">下载</el-button>
            </el-button-group>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    <el-pagination background="" @size-change="handleSizeChange" @current-change="handleCurrentChange" @on-success="handleSuccess"
      layout="total, sizes,prev, pager, next,jumper" :current-page.sync="state.listQuery.page" :page-size="state.listQuery.limit"
      :page-sizes="[5, 10, 15, 20, 50]" :total="state.gridFsFileList.total"></el-pagination>

    <el-dialog title="查看文件" :before-close="handleClose" width="60%" top="80px" :center="true" :destroy-on-close="true" v-model="state.dialogShowImageVisible">
      <el-image :src="state.imageShowUrl">
        <div class="image-slot">
          加载中
          <span class="dot">...</span>
        </div>
      </el-image>
    </el-dialog>
    <el-dialog title="上传文件" :before-close="handleClose" width="60%" top="80px" :center="true" :destroy-on-close="true" v-model="state.dialogShowUploadVisible">
      <el-card class="operate-container" shadow="never">
        <el-form :model="state.uploadParams">
          <el-form-item label="文件使用权限">
            <el-radio-group v-model="state.uploadParams.fileAuthRange">
              <el-radio label="personal">私人文件</el-radio>
              <el-radio label="resource" v-if="state.pageType == 'admin'">资源文件</el-radio>
              <el-radio label="public">公共文件</el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="备注信息">
            <el-input v-model.number="state.uploadParams.remark" class="input-width" placeholder="备注信息"></el-input>
          </el-form-item>
          <el-form-item label="文件标签（tag）">
            <el-input v-model.number="state.uploadParams.tag" class="input-width" placeholder="文件标签（tag）"></el-input>
          </el-form-item>
        </el-form>
        <el-upload multiple :limit="10" class="upload-demo" ref="upload" :action="uploadActionUrl()" :on-preview="handlePreview" :on-remove="handleRemove"
          :headers="state.headers" :on-success="handleSuccess" :on-error="handError" :data="state.uploadParams" :file-list="state.fileList"
          :auto-upload="false">
          <template #trigger>
            <el-button size="small" type="primary">选取文件</el-button>
          </template>
          <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button>
          <el-button size="small" @click="state.fileList = []">清空文件列表</el-button>
          <template #tip>
            <div class="el-upload__tip">最多一次上传10个文件</div>
          </template>
          <!-- <div slot="tip" class="el-upload__tip">只能上传jpg/png文件，且不超过500kb</div> -->
        </el-upload>

      </el-card>
    </el-dialog>





  </el-card>


</template>

<script setup lang="ts" name="gridfsPage">

import { onMounted, reactive, ref, defineProps } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';

import { mongoGridfsApi } from '/@/api/mongo/mongoGridFs';
import { Session } from '/@/utils/storage';
import { formatDate } from '/@/utils/formatTime';



const upload = ref();
const dataListTable = ref();

const multipleSelection = ref<any[]>([])

// defineProps<{ type: String, typeName: String }>()

const props = defineProps({ pageType: String, pageName: String })

const qureyParams = {
  _id: null,
  filename: null,
  minSize: null,
  maxSize: null,
  uploadDate: null,
  metadata: {
    contentType: null, //文件类型
    suffix: null, //文件后缀
    fileAuthRange: null,
    ownerName: null
  }
};
const defaultListQuery = {
  page: 1,
  limit: 10,
  params: qureyParams
};

const handleSelectionChange = (val: any[]) => {
  multipleSelection.value = val
};



const state = reactive({
  fileList: [],
  gridFsFileList: {
    list: [],
    total: 0,
  },
  fileType: [
    {
      name: "图片",
      value:
        "(?i)^\\.(?=Webp|BMP|PCX|TIF|GIF|JPG|JPEG|TGA|EXIF|FPX|SVG|PSD|CDR|PCD|DXF|PNG|HDRI|RAW|AI|WMF|FLIC|EMF|ICO).*$"
    },
    { name: "文档", value: "(?i)^\\.(?=xlsx?|pptx?|docx?|pdf|md|wps).*$" },
    { name: "网页文件", value: "(?i)^\\.(?=html|htm|js|vue).*$" },
    { name: "全部", value: null }
  ],
  listQuery: Object.assign({}, defaultListQuery),
  headers: { Authorization: Session.get('token') },
  dialogShowImageVisible: false,
  dialogShowUploadVisible: false,
  imageShowUrl: "",
  pageType: "admin",
  uploadParams: {
    remark: null, // 备注
    tag: null, // 文件标签，随便输入
    fileAuthRange: "personal" // resource 为资源文件 personal 个人文件  public 公开文件
  },
  fileAuthList: []
}
);

onMounted(() => {
  state.pageType = props.pageType ? props.pageType : "admin";
  query();
});


const submitUpload = () => {
  upload.value.submit();
};

const handleRemove = function (file: any, fileList: any) { };
const handleSuccess = function (response: any, file: any, fileList: any) {
  query();
  state.fileList = [];
};

const handError = function (err: { message: string; }, file: { name: string; }, fileList: any[]) {
  ElMessage.success(file.name + "上传失败，" + err.message);
  fileList.push(file);
};

const handlePreview = (file: any) => { };

const clearFileList = () => {
  state.fileList = [];
};
const uploadActionUrl = () => {
  return (
    import.meta.env.VITE_PHOTO_API_URL + "/COMMON-SERVICE/personal/mongo/gridfs/upload"
  );
};
const query = function () {
  mongoGridfsApi().queryGridFs(
    state.pageType,
    state.listQuery.page,
    state.listQuery.limit,
    state.listQuery.params
  ).then((response) => {
    state.gridFsFileList = response;
  });
};

const handleResetSearch = function () {
  state.listQuery["params"] = Object.assign({}, qureyParams);
  state.listQuery["params"]["metadata"] = Object.assign(
    {},
    qureyParams.metadata
  );
};

const handleSizeChange = function (val: any) {
  state.listQuery.page = 1;
  state.listQuery.limit = val;
  query();
};
const handleCurrentChange = function (val: any) {
  state.listQuery.page = val;
  query();
};
const handleDelete = function () {
  // console.log(dataListTable.value.store?.states);
  let selectRows = multipleSelection.value;
  let fileIds: never[] = [];
  if (selectRows.length && selectRows.length == 0) {
    return;
  }
  selectRows.forEach((element: { _id: any; }) => {
    fileIds.push(element._id);
  });
  mongoGridfsApi().deleteFiles(state.pageType, fileIds).then((response: any) => {
    ElMessage.success("删除成功，共计删除【" + fileIds.length + "】条");
    query();
  });
};
const handleDeleteOne = function (_id: any) {
  let fileIds = [_id];
  mongoGridfsApi().deleteFiles(state.pageType, fileIds).then((response: any) => {
    ElMessage.success("删除成功，共计删除【" + fileIds.length + "】条");
    query();
  });
};
const handleDownload = function (_id: any, filename: string, contentType: any) {
  mongoGridfsApi().downloadFileByAdmin(state.pageType, _id).then((response: any) => {
    if (window.navigator.msSaveOrOpenBlob) {
      navigator.msSaveBlob(response, filename);
    } else {
      var link = document.createElement("a");
      link.href = window.URL.createObjectURL(response);
      link.download = filename;
      link.click();
      window.URL.revokeObjectURL(link.href);
    }
  });
};

const handleShowImage = function (_id: any, filename: any, contentType: any) {
  mongoGridfsApi().showFileByAdmin(state.pageType, _id).then((response: any) => {
    state.imageShowUrl = window.URL.createObjectURL(response);
    state.dialogShowImageVisible = true;
  });
};

const openUploadDialog = function () {
  state.fileList = [];
  state.dialogShowUploadVisible = true;
};

const handleClose = function (done: () => void) {
  ElMessageBox.confirm("确认关闭？", '提示', {
    confirmButtonText: '确认',
    cancelButtonText: "取消"
  }).then(async () => {
    try {
      done();
    } catch (error: any) {
      ElMessage.error(error.msg);
    }
  });
};


</script>
<style scoped lang="scss">
.el-form .el-form-item:last-of-type {
  margin-bottom: 22px !important;
}

.bar_tools {
  display: flex;
  flex-direction: row-reverse;
  margin-bottom: 10px;
}


.bar_btn_div {
  display: flex;
  padding: 20px;
  border: 1px solid #ebeef5;
  align-items: center;
  justify-content: space-between;
  border-radius: 5px 5px 0px 0px;

  .title_div {
    display: flex;
    font-size: 16px;

    &>div {
      margin-right: 10px;
    }
  }
}

.search_div {
  border: 1px solid #ebeef5;
  border-top: 0px;
  border-radius: 0px 0px 5px 5px;
  padding: 20px;
  padding-bottom: 0px;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}

.avatar {
  width: 178px;
  height: 178px;
  display: block;
}
</style>